package com.smartfast4j.backend.modules.sys.controller;

import com.smartfast4j.backend.common.bean.R;
import com.smartfast4j.backend.common.controller.WebBaseController;
import com.smartfast4j.backend.common.util.RSAUtils;
import com.smartfast4j.backend.modules.sys.security.shiro.MyShiroFilterFactoryBean;
import com.smartfast4j.backend.modules.sys.security.shiro.SysUserRealm;
import com.smartfast4j.backend.modules.sys.security.shiro.cache.RedisManager;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * Created by gacl on 2017/9/8.
 */
@RestController
@RequestMapping("/sys/tool")
public class SysToolController extends WebBaseController {

    @Autowired
    private SysUserRealm userRealm;

    @Autowired
    private RedisManager redisManager;

    //自定义的拦截工厂
    @Autowired
    private MyShiroFilterFactoryBean myShiroFilterFactoryBean;

    /**
     * 清除登录认证缓存信息
     * @return
     */
    @RequestMapping("/clearShiroCachedAuthenticationInfo")
    public R clearShiroCachedAuthenticationInfo(){
        userRealm.clearCachedAuthenticationInfo();
        return R.ok();
    }

    /**
     * 清除身份验证缓存信息
     * @return
     */
    @RequestMapping("/clearShiroCachedAuthorizationInfo")
    public R clearShiroCachedAuthorizationInfo() {
        userRealm.clearCachedAuthorizationInfo();
        return R.ok();
    }

    /**
     * 清除Shiro缓存信息
     * @return
     */
    @RequestMapping("/clearCached")
    public R clearShiroCached(){
        userRealm.clearCachedAuthenticationInfo();
        userRealm.clearCachedAuthorizationInfo();
        return R.ok();
    }

    /**
     * 获取缓存key值信息
     * @return
     */
    @RequestMapping("/getCacheKeysInfo")
    public R getCacheKeysInfo(){
        Map<String,Object> dataMap = new HashMap<>();
        Set<byte[]> keySet = redisManager.keys("*");
        List<String> keyList = new ArrayList<>();
        for(byte[] b:keySet){
            keyList.add(new String(b));
        }
        dataMap.put("keyList",keyList);
        return R.ok(dataMap);
    }

    /**
     * 获取缓存信息
     * @return
     */
    @RequestMapping("/getCacheInfo")
    public R getCacheInfo(){
        Map<String,Object> dataMap = new HashMap<>();
        Set<byte[]> keySet = redisManager.keys("*");
        for(byte[] b:keySet){
            dataMap.put(new String(b),new String(redisManager.get(b)));
        }
        return R.ok(dataMap);
    }

    /**
     * 清空缓存信息
     * @return
     */
    @RequestMapping("/clearCacheInfo")
    public R clearCacheInfo(){
        redisManager.flushDB();
        return R.ok();
    }

    /**
     * 获取RSA加密公钥
     * @return
     */
    @RequestMapping("/getRsaPublicKey")
    public R getRsaPublicKey(){
        // 将RSA公钥的 modulus 和 exponent 传给页面
        Map<String, Object> publicKeyMap = RSAUtils.getPublicKeyMap();
        return R.okEncrypt(publicKeyMap);
    }

    /**
     * 更新shiro权限
     * @return
     */
    @RequestMapping(value = "/updatePermission")
    public Map<String, String> updatePermission() {
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/sys/tool/getCacheInfo","anon");
        filterMap.put("/sys/tool/getCacheKeysInfo","anon");
        filterMap.put("/sys/sysUser/**","permission[sys:user:list,sys:user:info]");
        updatePermission(filterMap);
        return myShiroFilterFactoryBean.getFilterChainDefinitionMap();
    }

    /**
     * 动态更新新的权限
     * @param filterMap
     */
    private synchronized void updatePermission(Map<String, String> filterMap) {

        AbstractShiroFilter shiroFilter = null;
        try {
            shiroFilter = (AbstractShiroFilter) myShiroFilterFactoryBean.getObject();
            // 获取过滤管理器
            PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter.getFilterChainResolver();
            DefaultFilterChainManager filterManager = (DefaultFilterChainManager) filterChainResolver.getFilterChainManager();
            //清空拦截管理器中的存储
            filterManager.getFilterChains().clear();
            /*
            清空拦截工厂中的存储,如果不清空这里,还会把之前的带进去
            ps:如果仅仅是更新的话,可以根据这里的 map 遍历数据修改,重新整理好权限再一起添加
             */
            //myShiroFilterFactoryBean.getFilterChainDefinitionMap().clear();

            // 相当于新建的 map, 因为已经清空了
            Map<String, String> chains = myShiroFilterFactoryBean.getFilterChainDefinitionMap();
            //把修改后的 map 放进去
            chains.putAll(filterMap);

            //这个相当于是全量添加
            for (Map.Entry<String, String> entry : filterMap.entrySet()) {
                //要拦截的地址
                String url = entry.getKey().trim().replace(" ", "");
                //地址持有的权限
                String chainDefinition = entry.getValue().trim().replace(" ", "");
                //生成拦截
                filterManager.createChain(url, chainDefinition);
            }
        } catch (Exception e) {
            logger.error("updatePermission error,filterMap=" + filterMap, e);
        }
    }
}
